import "./index.less";
import { defineComponent, ref, watchSyncEffect, withDirectives } from "vue";
import {
  booleanType,
  arrayType,
  stringType,
} from "ant-design-vue/es/_util/type.js";
import { ElTable, ElAutoResizer, vLoading, ElScrollbar } from "element-plus";
import { isEmpty, isFunction, omit } from "lodash-es";

export default defineComponent({
  name: "BaseTable",
  props: {
    selectRow: arrayType([]),
    title: stringType("搜索列表"),
    theme: stringType(""),
    loading: booleanType(false),
    selection: booleanType(false), //多选
    showPagination: booleanType(true),
    column: arrayType([]),
    dataSource: arrayType([]),
    pageNum: {
      type: Number,
      default: 1,
    },
    rowKey: {
      type: String,
      default: undefined,
    },
    pageSize: {
      type: Number,
      default: 10,
    },
    total: {
      type: Number,
      default: 0,
    },
    border: {
      type: Boolean,
      default: true,
    },
    showTool: {
      type: Boolean,
      default: true,
    },
    spanMethod: {
      type: Function,
    },
    autoScroll: {
      type: Boolean,
      default: false,
    },
  },
  slots: {
    tools: null,
  },
  emits: ["page-change", "update:select-row", "sort-change"],
  setup(props, { slots, emit, expose }) {
    // debugger;
    const cachedColumnSettingKey = ref([]);
    const cachedColumn = ref([]);
    const tableRef = ref(null);
    const wrapRef = ref(null);

    let scrollTimer = null;

    const startAutoScroll = () => {
      const tableBody = tableRef.value?.$el?.querySelector(
        ".el-scrollbar__wrap",
      );
      if (!tableBody) return;

      clearInterval(scrollTimer); // 清理旧定时器
      scrollTimer = setInterval(() => {
        tableBody.scrollTop += 1;

        if (
          tableBody.scrollTop + tableBody.clientHeight >=
          tableBody.scrollHeight
        ) {
          tableBody.scrollTop = 0;
        }
      }, 30);
    };

    onMounted(() => {
      if (props.autoScroll) {
        startAutoScroll();
      }
    });

    onUnmounted(() => {
      clearInterval(scrollTimer);
    });
    const headerCheck = ref({
      checked: false,
      indeterminate: false,
    });

    watchSyncEffect(() => {
      cachedColumn.value = props.column;
      cachedColumnSettingKey.value = cachedColumn.value.map(
        (item) => item.dataKey || item.key,
      );
      headerCheck.value.checked = true;
      headerCheck.value.indeterminate = false;
    });

    const handleTableHeaderCheck = (v) => {
      headerCheck.value.checked = v.target.checked;
      headerCheck.value.indeterminate = false;
      if (!v.target.checked) {
        cachedColumnSettingKey.value = [];
      } else {
        cachedColumnSettingKey.value = props.column.map(
          (item) => item.dataKey || item.key,
        );
      }
    };
    const handleTableCheckGroup = (v) => {
      cachedColumnSettingKey.value = v;
      check();
    };
    const handleTableCheckTap = (v) => {
      cachedColumnSettingKey.value = cachedColumn.value.map(
        (item) => item.dataKey || item.key,
      );
      headerCheck.value.checked = true;
      headerCheck.value.indeterminate = false;
      tableRef.value?.doLayout();
    };

    const check = () => {
      if (cachedColumnSettingKey.value.length === cachedColumn.value.length) {
        headerCheck.value.checked = true;
        headerCheck.value.indeterminate = false;
        return false;
      }
      if (cachedColumnSettingKey.value.length <= 0) {
        headerCheck.value.checked = false;
        headerCheck.value.indeterminate = false;
        return false;
      }
      if (cachedColumnSettingKey.value.length !== cachedColumn.value.length) {
        headerCheck.value.checked = false;
        headerCheck.value.indeterminate = true;
        return false;
      }
    };

    const onSelectionChange = (v) => {
      emit("update:select-row", v);
    };

    const toggleRowSelectionRow = (item, selected) => {
      console.log(item, selected, tableRef.value);
      return tableRef.value?.toggleRowSelection(item, selected);
    };

    expose({ tableRef, toggleRowSelectionRow });

    return () => {
      return (
        <div class={["base-table", `base-table-${props.theme}`]}>
          {props.showTool ? (
            <div class="base-table-header">
              <div class="base-table-header-left">
                <a-space>
                  <span>{props.title}</span>
                  {slots?.leftTools?.()}
                </a-space>
              </div>
              <div class="base-table-header-right">
                <a-space>
                  {slots?.tools?.()}
                  <a-popover
                    trigger={["click"]}
                    arrowPointAtCenter
                    overlayClassName="base-table-header-right-overlay"
                    placement="right"
                    v-slots={{
                      title: () => (
                        <div class="base-table-column-title">
                          <div class="base-table-column-title-left">
                            <a-checkbox
                              checked={headerCheck.value.checked}
                              indeterminate={headerCheck.value.indeterminate}
                              onChange={(v) => handleTableHeaderCheck(v)}
                            >
                              列设置
                            </a-checkbox>
                          </div>
                          <div class="base-table-column-title-right">
                            <a-button
                              type="link"
                              onClick={() => handleTableCheckTap()}
                            >
                              重置
                            </a-button>
                          </div>
                        </div>
                      ),
                      content: () => (
                        <div
                          class={[
                            "base-table-column-overlay",
                            props.column.length >= 30
                              ? "base-table-column-overlay-scroll"
                              : "",
                          ]}
                        >
                          {props.column.length >= 30 ? (
                            <ElScrollbar>
                              <a-checkbox-group
                                value={cachedColumnSettingKey.value}
                                onChange={(v) => handleTableCheckGroup(v)}
                              >
                                <a-space wrap>
                                  {props.column.map((item) => {
                                    return (
                                      <a-checkbox
                                        value={item.dataIndex || item.key}
                                      >
                                        <div className="base-table-column-title">
                                          {item.title}
                                        </div>
                                      </a-checkbox>
                                    );
                                  })}
                                </a-space>
                              </a-checkbox-group>
                            </ElScrollbar>
                          ) : (
                            <a-checkbox-group
                              value={cachedColumnSettingKey.value}
                              onChange={(v) => handleTableCheckGroup(v)}
                            >
                              <a-space wrap>
                                {props.column.map((item) => {
                                  return (
                                    <a-checkbox
                                      value={item.dataIndex || item.key}
                                    >
                                      <div className="base-table-column-title">
                                        {item.title}
                                      </div>
                                    </a-checkbox>
                                  );
                                })}
                              </a-space>
                            </a-checkbox-group>
                          )}
                        </div>
                      ),
                    }}
                  >
                    <div class="base-table-column">
                      <a-tooltip title="列设置">
                        <div class="base-table-column-icon">列设置</div>
                      </a-tooltip>
                    </div>
                  </a-popover>
                </a-space>
              </div>
            </div>
          ) : null}

          {withDirectives(
            <div class="base-table-footer">
              <ElAutoResizer
                v-slots={{
                  default: ({ height, width }) => {
                    return (
                      <ElTable
                        ref={tableRef}
                        {...{
                          data: props.dataSource ?? [],
                          width,
                          height,
                          border: props.border,
                          stripe: false,
                          fixed: true,
                          spanMethod: props.spanMethod,
                        }}
                        row-key={props.rowKey}
                        v-slots={{
                          empty: () => <a-empty />,
                        }}
                        onSortChange={(v) => {
                          let order =
                            v.order == "descending"
                              ? "desc"
                              : v.order == "ascending"
                                ? "asc"
                                : v.order;
                          emit("sort-change", { ...v, order });
                        }}
                        onSelectionChange={(v) => onSelectionChange(v)}
                      >
                        {props.selection ? (
                          <el-table-column type="selection" width="55" />
                        ) : null}
                        {(cachedColumn.value ?? [])
                          .filter((v) =>
                            cachedColumnSettingKey.value.includes(
                              v.dataKey || v.key,
                            ),
                          )
                          .map((item) => {
                            if (item.scopedSlots) {
                              return (
                                <el-table-column
                                  prop={item.key || item.dataKey}
                                  label={item.title}
                                  {...omit(item, "children")}
                                  v-slots={{
                                    default: ({ $index, row }) => {
                                      return item.children?.length
                                        ? item.children.map((c) => {
                                            return (
                                              <el-table-column
                                                prop={c.key || c.dataKey}
                                                label={c.title}
                                                {...c}
                                                v-slots={{
                                                  default: ({
                                                    $index,
                                                    row,
                                                  }) => {
                                                    return !isEmpty(
                                                      slots[
                                                        c.scopedSlots
                                                          ?.customRender
                                                      ],
                                                    )
                                                      ? slots[
                                                          c.scopedSlots
                                                            .customRender
                                                        ]?.(
                                                          row[c.key],
                                                          row,
                                                          $index,
                                                        )
                                                      : row[c.key] ||
                                                          row[c.key] === 0
                                                        ? row[c.key]
                                                        : "--";
                                                  },
                                                }}
                                              ></el-table-column>
                                            );
                                          })
                                        : !isEmpty(
                                              slots[
                                                item.scopedSlots.customRender
                                              ],
                                            )
                                          ? slots[
                                              item.scopedSlots.customRender
                                            ]?.(row[item.key], row, $index)
                                          : row[item.key] || row[item.key] === 0
                                            ? row[item.key]
                                            : "--";
                                    },
                                  }}
                                ></el-table-column>
                              );
                            } else {
                              return (
                                <el-table-column
                                  prop={item.key}
                                  label={item.title}
                                  {...omit(item, "children")}
                                  v-slots={{
                                    default: ({ $index, row }) => {
                                      if (item.children?.length) {
                                        return item.children.map((c) => {
                                          return (
                                            <el-table-column
                                              prop={c.key || c.dataKey}
                                              label={c.title}
                                              {...c}
                                              v-slots={{
                                                default: ({ $index, row }) => {
                                                  return !isEmpty(
                                                    slots[
                                                      c.scopedSlots
                                                        ?.customRender
                                                    ],
                                                  )
                                                    ? slots[
                                                        c.scopedSlots
                                                          .customRender
                                                      ]?.(
                                                        row[c.key],
                                                        row,
                                                        $index,
                                                      )
                                                    : row[c.key] ||
                                                        row[c.key] === 0
                                                      ? row[c.key]
                                                      : "--";
                                                },
                                              }}
                                            ></el-table-column>
                                          );
                                        });
                                      }

                                      if (isFunction(item.customRender)) {
                                        return (
                                          item.customRender(
                                            row[item.key],
                                            row,
                                            $index,
                                          ) || "--"
                                        );
                                      } else {
                                        return row[item.key] ||
                                          row[item.key] === 0
                                          ? row[item.key]
                                          : "--";
                                      }
                                    },
                                  }}
                                ></el-table-column>
                              );
                            }
                          })}
                      </ElTable>
                    );
                  },
                }}
              />
            </div>,
            [[vLoading, props.loading]],
          )}
          {props.showPagination ? (
            <div class="base-table-pagination">
              <div class="base-table-pagination-left">
                共{Math.ceil(props.total / props.pageSize)}页，
                {props.total}行数据，当前第
                {props.total === 0 ? 0 : props.pageNum}页
              </div>
              <div class="base-table-pagination-right">
                <a-pagination
                  showSizeChanger={false}
                  showLessItems={true}
                  hideOnSinglePage={false}
                  current={props.pageNum}
                  pageSize={props.pageSize}
                  total={props.total}
                  onChange={(v, pageSize) => {
                    emit("page-change", v, pageSize);
                  }}
                  v-slots={{
                    itemRender: ({ current, type, originalElement }) => {
                      if (type === "prev") {
                        return <a>上一页</a>;
                      } else if (type === "next") {
                        return <a>下一页</a>;
                      }
                      return originalElement;
                    },
                  }}
                />
              </div>
            </div>
          ) : null}
        </div>
      );
    };
  },
});
